import { JKManager } from "../JKManager";
import { TaskQueueTool } from "../Utils/TaskQueueTool";

const { ccclass, property } = cc._decorator;

let FlagMoveTime = 0.1 // 下划线标记移动时间，秒

/**
 * 导航栏组件
 */
@ccclass
export class NavigationCpnt extends cc.Component {
    @property(cc.Integer)
    itemSpace: number = 0

    _taskQueueTool: TaskQueueTool;
    scrollView: cc.ScrollView;
    ndCtn: cc.Node;
    wdgtCtn: cc.Widget;
    lyotCtn: cc.Layout;
    ndBottomSp: cc.Node;
    private _bottomFlagabled: boolean;
    private _curSelectedIndex: number;
    private _selectedCall: (item: cc.Node, index: number) => void;
    private _curItem: cc.Node;
    private _totalCnt: number;
    private _createCall: (index: number) => cc.Node;
    private _activeCall: (item: cc.Node, index: number) => void;

    onLoad() {
        cc.log(`${cc.js.getClassName(this)} onLoad`)
        
        this._taskQueueTool = new TaskQueueTool()

        this.scrollView = cc.find(`ndSv`, this.node).getComponent(cc.ScrollView)
        this.ndCtn = this.scrollView.content
        this.wdgtCtn = this.ndCtn.getComponent(cc.Widget)
        this.lyotCtn = this.ndCtn.getComponent(cc.Layout)
        this.ndBottomSp = cc.find(`ndBottomSp`, this.ndCtn.parent)
        this.lyotCtn.spacingX = this.lyotCtn.paddingLeft = this.lyotCtn.paddingRight = this.itemSpace
        this._bottomFlagabled = true
        this._curSelectedIndex = 0
    }

    update(dt: number) {
        this._taskQueueTool.doCmd()
    }

    // ====================================================================================
    // ===================================== 内部接口 ======================================
    // ====================================================================================

    /**
     * 移动下划线
     * @param time 下划线标记移动时间
     */
    private _moveFlag(time = FlagMoveTime) {
        // cc.log(`${cc.js.getClassName(this)} _moveFlag time = ${time}`)

        let targetPos = this.ndCtn.parent.convertToNodeSpaceAR(this._curItem.parent.convertToWorldSpaceAR(this._curItem.position)),
            targetWidth = this._curItem.width
        cc.tween(this.ndBottomSp)
            .to(time, {
                x: targetPos.x,
                width: targetWidth,
            }).call(() => {
                this.ndBottomSp.x = targetPos.x
                this.ndBottomSp.width = targetWidth
            })
            .start()
    }

    /**
     * 选择
     * @param item 选项
     * @param index 序号
     * @param time 下划线标记移动时间
     */
    private _select(item: cc.Node, index: number, time: number = FlagMoveTime) {
        cc.log(`${cc.js.getClassName(this)} _select index = ${index}`)

        this._curSelectedIndex = index
        this._selectedCall && this._selectedCall(item, this._curSelectedIndex)
        this._curItem = item
        this._moveFlag(time)
    }

    // ====================================================================================
    // ===================================== 外部接口 ======================================
    // ====================================================================================

    /**
     * 初始化导航列表
     * @param totalCnt 列表节点数量
     * @param createCall 滑动节点创建回调 createCall(index 节点索引) return cc.Node item
     * @param activeCall 进入视窗的回调 activeCall(item 节点, index 节点索引)
     * @param selectedCall 选中回调 selectedCall(item 节点, index 节点索引)
     */
    init(totalCnt: number, createCall: (index: number) => cc.Node, activeCall: (item: cc.Node, index: number) => void, selectedCall: (item: cc.Node, index: number) => void) {
        cc.log(`${cc.js.getClassName(this)} init totalCnt = ${totalCnt}`)

        this._totalCnt = totalCnt
        this._createCall = createCall
        this._activeCall = activeCall
        this._selectedCall = selectedCall
        this.ndCtn.removeAllChildren()
        for (let index = 0; index < this._totalCnt; index++) {
            let item = this._createCall(index)
            this.ndCtn.addChild(item)
            this._activeCall(item, index)
            item.on(cc.Node.EventType.TOUCH_END, (event: cc.Event.EventTouch) => {
                this._select(item, index)
            }, this)
        }
        this.lyotCtn.updateLayout()
    }

    /**
     * 选择导航按钮
     * @param index 序号
     * @param time 下划线标记移动时间
     */
    selectIndex(index: number, time: number) {
        cc.log(`${cc.js.getClassName(this)} selectIndex index = ${index}`)

       let item = this.ndCtn.children[index]
       this._select(item, index, time)
    }

    /**
     * 设置列表项间隔
     * @param itemSpace 间隔
     */
    setItemSpace(itemSpace: number) {
        cc.log(`${cc.js.getClassName(this)} setItemSpace itemSpace = ${itemSpace}`)

        this.itemSpace = itemSpace
        this.lyotCtn.spacingX = this.lyotCtn.paddingLeft = this.lyotCtn.paddingRight = this.itemSpace
        this.lyotCtn.updateLayout()
    }

    // 获取所有按钮节点
    getItems() {
        cc.log(`${cc.js.getClassName(this)} getItems`)

        return JKManager.Utils.copyObj(this.ndCtn.children)
    }

    /**
     * 设置是否显示选项下标记
     * @param bool 是否显示选项下标记
     */
    setBottomFlagAbled(bool: boolean) {
        // cc.log(`${cc.js.getClassName(this)} setBottomFlagAbled ` + bool)

        this._bottomFlagabled = !!bool
        this.ndBottomSp.active = this._bottomFlagabled
    }

    /**
     * 设置选项下标记颜色
     * @param color 颜色
     */
    setBottomFlagColor(color: cc.Color) {
        // cc.log(`${cc.js.getClassName(this)} setBottomFlagColor color = ${color}`)

        this.ndBottomSp.color = color
    }

    /**
     * 设置是否可滑动，初始化时设置一次
     * @param bool 是否可滑动
     * @param isChildrenLyot 是否均分尺寸布局
     */
    setScrollabled(bool: boolean, isChildrenLyot = true) {
        // cc.log(`${cc.js.getClassName(this)} setScrollabled ` + bool)

        this.scrollView.enabled = bool
        this.ndCtn.x = 0
        if (isChildrenLyot) {
            this.wdgtCtn.target = this.node
            this.wdgtCtn.isAlignTop = true
            this.wdgtCtn.isAlignBottom = true
            this.wdgtCtn.isAlignLeft = true
            this.wdgtCtn.isAlignRight = true
            this.wdgtCtn.top = 0
            this.wdgtCtn.bottom = 0
            this.wdgtCtn.left = 0
            this.wdgtCtn.right = 0
            this.wdgtCtn.updateAlignment()
            this.lyotCtn.updateLayout()
        }
    }

    /**
     * 滑到最左侧
     */
    scrollToLeft() {
        // cc.log(`${cc.js.getClassName(this)} scrollToLeft`)

        this.scrollView.scrollToLeft()
    }

    /**
     * 设置是否可回弹
     * @param bool 是否可回弹
     */
    setElastic(bool: boolean) {
        // cc.log(`${cc.js.getClassName(this)} setElastic ` + bool)

        this.scrollView.elastic = bool
    }

    getCurSelectedIndex() {
        return this._curSelectedIndex
    }
}
